package filter

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"log"
	"strings"
	"time"
	"wish_go/src/main/com/ajie/common"
	"wish_go/src/main/com/ajie/model"
	"wish_go/src/main/com/ajie/result"
)

func AuthFilter() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		// 获取请求头
		Authorization := ctx.GetHeader(viper.GetString("jwt.tokenHeader"))
		// 判断token是否有效
		if len(Authorization) == 0 {
			result.Error(ctx, 401, "尚未登陆，请登录")
			// 抛弃请求
			ctx.Abort()
			return
		}
		if !strings.HasPrefix(Authorization, viper.GetString("jwt.tokenHead")) {
			result.Error(ctx, 403, "权限不足")
			// 抛弃请求
			ctx.Abort()
			return
		}
		// 解析token内容 去掉'Bearer '
		tokenString := Authorization[7:]
		token, claims, err := common.ParseToken(tokenString)
		if err != nil || !token.Valid {
			fmt.Print("解析结果：", claims, "\n异常信息:", err)
			result.Error(ctx, 401, "token已过期")
			// 抛弃请求
			ctx.Abort()
			return
		}
		// 获取token中的userId 从数据库中查找用户信息
		db := common.GetDB()
		user := model.User{}
		db.First(&user, claims.UserId)
		if user.Id == 0 {
			result.Error(ctx, 401, "token无效")
			// 抛弃请求
			ctx.Abort()
			return
		}
		// 判断token 是否快过期
		// 即将超过过期时间，则添加一个http header `new-token` 给前端更新
		expires := claims.ExpiresAt - time.Now().Unix()
		if expires <= viper.GetInt64("jwt.refreshTime")*60*60*24 {
			generateToken, tokenErr := common.GenerateToken(user)
			if tokenErr != nil {
				result.Error(ctx, 500, "系统异常")
				log.Printf("token生成失败: %v", err)
				// 抛弃请求
				ctx.Abort()
				return
			}
			// 返回新的token
			ctx.Header("refreshToken", viper.GetString("jwt.tokenHead")+generateToken)
		}
		// 将用户信息存入当前线程的上下文中
		ctx.Set("user", user)
		ctx.Next()
	}
}
